package cn.wen.service.impl;

import cn.wen.common.enums.Role;
import cn.wen.common.utils.DateUtils;
import cn.wen.common.utils.ResultEntity;
import cn.wen.dao.CollectLikeDao;
import cn.wen.dao.GoodsDao;
import cn.wen.dao.UserDao;
import cn.wen.entity.NoticesEntity;
import cn.wen.entity.UserEntity;
import cn.wen.service.UserCacheService;
import cn.wen.service.UserService;
import cn.wen.shiro.StringUtil;
import cn.wen.vo.BrowsingGoodsVO;
import cn.wen.vo.UserGoodsVO;
import cn.wen.vo.UserVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;


@Service("userService")
@Component
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {

    @Value("${second-yaling.default-password}")
    private String DEFAULT_PASSWORD;

    @Autowired
    private UserCacheService userCacheService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserDao userDao;

    @Autowired
    private GoodsDao goodsDao;

    @Autowired
    private CollectLikeDao collectLikeDao;

    @Override
    public Map<String, Object> queryPage(Map<String, Object> params) {

        List<UserEntity> userLists = userDao.queryAllUser();

        PageInfo<UserEntity> pageInfo = new PageInfo<>();
        pageInfo.setList(userLists);

        Map<String, Object> map = new HashMap<>();
        map.put("page",pageInfo);
        return map;
    }

    @Override
    public UserEntity getUserByAccount(String account) {

        // 需要先判断redis中是否存在该数据
        UserEntity user = userCacheService.getUser(account);
        if (user != null) return user;
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",account).
                or().
                eq("user_phone",account);
        user = userDao.selectOne(wrapper);
        // 存储到缓存 需要判断是哪个类型来查找  如果是userId则是true  然后是userPhone 是false
        userCacheService.setUser(user, account.length() == 8 ? true : false);
        return user;
    }

    @Override
    public UserEntity getUserByAccountDB(String account) {
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",account).
                or().
                eq("user_phone",account);
        UserEntity user = userDao.selectOne(wrapper);
        return user;
    }

    /**
     * 通过创建特定的ID
     * 默认添加普通用户的权限
     * @param userPhone
     */
    @Override
    public void insert(String userPhone) {
        UserEntity user = new UserEntity();
        user.setUserId(userSerialNumber());
        user.setPassword(StringUtil.md5(DEFAULT_PASSWORD));
        user.setUserPhone(userPhone);
        user.setCreateTime(new Date());
        userDao.insert(user);
        // 赋予用户权限
        userDao.endowRoleToUser(user.getUserId(), Role.GENERAL.getCode());
    }

    /**
     * 判断账号是否已经注册
     * @param userPhone
     * @return
     */
    @Override
    public boolean checkUserByUserPhone(String userPhone) {
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_phone", userPhone);
        UserEntity dbUser = userDao.selectOne(wrapper);
        if (dbUser != null) {
            return true;
        }
        return false;
    }

    @Override
    public boolean updateUser(UserEntity userEntity) {
        userEntity.setUpdateTime(new Date());
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userEntity.getUserId());
        int result = userDao.update(userEntity, wrapper);
        // 同时需要修改缓存中的user数据
        userCacheService.delUser(userEntity.getUserId());
        // 删除之后再添加数据
        UserEntity dbUser = getUserByAccountDB(userEntity.getUserId());
        // 默认添加号码的
        userCacheService.setUser(dbUser, false);
        return result > 0;
    }

    @Override
    public Long getBrowsingHistoryNumByUser(String userId) {
        return userDao.selectBrowsingHistoryCountByUser(userId);
    }

    @Override
    public List<BrowsingGoodsVO> getBrowsingHistoryByUser(String userId) {
        // 先通过年月日分组查询
        List<String> groupMonthDay = goodsDao.findGroupByYearMonthDay(userId);
        List<BrowsingGoodsVO> browsingGoodsVOS = new ArrayList<>();
        for (String monthDay : groupMonthDay) {
            BrowsingGoodsVO browsingGoodsVO = new BrowsingGoodsVO();
            browsingGoodsVO.setGroupMonthDay(getTimeFormat(monthDay));
            browsingGoodsVO.setGoodsList(goodsDao.findGoodsByYearMonthDayAndUserId(monthDay, userId));
            browsingGoodsVOS.add(browsingGoodsVO);
        }
        return browsingGoodsVOS;
    }

    private static String getTimeFormat(String time) {
        String curTime = time.substring(5);
        String[] split = curTime.split("-");
        String month = split[0];
        String day = split[1];
        return Integer.parseInt(month) + "月" + Integer.parseInt(day) + "日";
    }

    @Override
    public UserVO getUserBaseInfoById(String userId) {
        return userDao.getUserBaseInfoByUserId(userId);
    }

    @Override
    public boolean deleteByUserIdAndGoodsId(String userId, String goodsId) {
        boolean isDelete = goodsDao.deleteBrowsByUserIdAndGoodsId(userId, goodsId);
        return isDelete;
    }

    /**
     * 用户自增序列  每月增长
     * 使用秒作为timeout
     * 对
     * @return
     */
    private String userSerialNumber() {

        SimpleDateFormat yyMMdd = new SimpleDateFormat("yyMM");
        String firstToSixthNumber = yyMMdd.format(new Date());
        if (redisTemplate.hasKey(firstToSixthNumber)) {
            redisTemplate.opsForValue().increment(firstToSixthNumber, 1);
        } else {
            redisTemplate.opsForValue().set(firstToSixthNumber, 0);
            redisTemplate.expire(firstToSixthNumber, DateUtils.getDaysOfMoth(), TimeUnit.SECONDS);
        }
        String tenthToFifteenthNumber = String.format("%04d", redisTemplate.opsForValue().get(firstToSixthNumber));
        return firstToSixthNumber + tenthToFifteenthNumber;
    }

}